package cbbx_sm.decision_maker.search;

import java.util.HashSet;

/**
 * A search driver which explores nodes in a BFS fashion, expending based on a frontier principle.
 * After several levels were generated the algorithm can return the sum of the scores of all children expended from any root node.
 *  
 * @author ronenvaisenberg
 *
 */
public class SearchDriver {

	private HashSet<SearchNode> frontierNodes;
	private int numberOfNodesVisited;
	
	
	public SearchDriver(SearchNode root){
		frontierNodes = new HashSet<SearchNode>();
		frontierNodes.add(root);
		numberOfNodesVisited = 0;
	}
	/**
	 * Generates the nodes in a level by level order.
	 *
	 */
	public HashSet<SearchNode> expandFrontierNodes(boolean onlyBestActions){
		HashSet<SearchNode> newFrontierNodes = new HashSet<SearchNode>();
		for (SearchNode frontierNode: frontierNodes){
			HashSet<SearchNode> frontierNodeSuccessors = frontierNode.getSuccessors();

			numberOfNodesVisited += frontierNodeSuccessors.size();	

			// Maintain the nodes which are on the last level at the frontier.
			if (frontierNodeSuccessors.size() == 0){
				newFrontierNodes.add(frontierNode);
			} else {
				if (onlyBestActions){
					for (SearchNode n: frontierNodeSuccessors){
						if (frontierNode.getBestNextAction().compareTo(n.getSelectedAction())==0){
							newFrontierNodes.add(n);
						}
					}
				} else {
					newFrontierNodes.addAll(frontierNodeSuccessors);					
				}
			}
		}
		frontierNodes = newFrontierNodes;
		
		return frontierNodes;
	}
	public int getNumberOfNodesVisited(){
		return numberOfNodesVisited;
	}	
}
